package com.sy.olddriver.servlet;

import com.sy.olddriver.constant.AppConstant;
import com.sy.olddriver.dto.MappingObj;
import com.sy.olddriver.utils.HttpUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 前端控制器，用于分发请求以及统一响应
 *
 * @author Administrator
 */
@WebServlet("/apis/*")
public class DispatcherServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //1.获取组件的路径
        // /apis
        String mappingUri = HttpUtils.getMappingUri(req);

        //2.从Servlet上下文中获取所有的映射信息，进行匹配，决定调用哪个处理器及其中的哪个方法
        List<MappingObj> mappingObjList = (List<MappingObj>) req.getServletContext().getAttribute(AppConstant.MAPPING_OBJS_SERVLET_CONTEXT_KEY);
        MappingObj mappingObj = null;
        for (MappingObj mo : mappingObjList) {
            if (mo.getHandlerMethodUrl().equals(mappingUri)) {
                mappingObj = mo;
            }
        }
        //如果没有找到映射信息
        if (null == mappingObj) {
            HttpUtils.writeJson(res, HttpUtils.buildFailure("请求路径" + mappingUri + "有误"));
            return;
        }

        //3.根据请求路径反射调用处理器方法！
        //(1)获取要调用的方法
        Method method = mappingObj.getHandlerMethod();
        //(2)获取要调用方法的实例对象
        Object handlerObj = mappingObj.getHandlerObj();
        try {
            //(3)反射调用处理器中的具体方法
            Object result = method.invoke(handlerObj);
            //(4)方法调用后的结果即为Handler中方法的调用结果
            //此时将这个结果以JSON格式写出即可
            HttpUtils.writeJson(res, result);
        } catch (Exception e) {
            e.printStackTrace();
            HttpUtils.writeJson(res, HttpUtils.buildFailure("未知错误"));
        }


    }
}
